package rensoft.android.view;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

import static rensoft.java.lang.Lang.error;


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

public class ImageViewBitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
  private final String url;
  private final ImageView imageView;

  public ImageViewBitmapDownloaderTask(ImageView imageView, String url) {
    this.imageView = imageView;
    this.url = url;
  }

  @Override
  protected Bitmap doInBackground(String... params) {
    return downloadBitmap(url);
  }

  @Override
  protected void onPostExecute(Bitmap bitmap) {
    imageView.setImageBitmap(bitmap);
  }

  private Bitmap downloadBitmap(String url) {
    HttpGet getRequest = new HttpGet(url);
    try {
      HttpResponse response = new DefaultHttpClient().execute(getRequest);
      final int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode != HttpStatus.SC_OK) {
        error("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
        return null;
      }
      final HttpEntity entity = response.getEntity();
      if (entity != null) {
        InputStream inputStream = null;
        try {
          inputStream = new FlushedInputStream(entity.getContent());
          final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
          return bitmap;
        } finally {
          if (inputStream != null) inputStream.close();
          entity.consumeContent();
        }
      }
    } catch (Exception e) {
      getRequest.abort();
      error("ImageDownloader", "Error while retrieving bitmap from " + url, e.toString());
    }
    return null;
  }

  class FlushedInputStream extends FilterInputStream {
    public FlushedInputStream(InputStream inputStream) {
      super(inputStream);
    }

    @Override
    public long skip(long n) throws IOException {
      long totalBytesSkipped = 0L;
      while (totalBytesSkipped < n) {
        long bytesSkipped = in.skip(n - totalBytesSkipped);
        if (bytesSkipped == 0L) {
          int oneByte = read();
          if (oneByte < 0)
            break; // we reached EOF
          else bytesSkipped = 1; // we read one byte
        }
        totalBytesSkipped += bytesSkipped;
      }
      return totalBytesSkipped;
    }
  }
}